#ifndef _ASYNCLOG_H
#define _ASYNCLOG_H

enum LOG_LEVEL
{
    LOG_LEVEL_TRACE,
    LOG_LEVEL_DEBUG,
    LOG_LEVEL_INFO,
    LOG_LEVEL_WARN,
    LOG_LEVEL_ERROR,    //业务错误
    LOG_LEVEL_SYSERR,   //框架错误
    LOG_LEVEL_FATAL,    //导致退出
    LOG_LEVEL_CRITICAL  //总是输出
};


#define LOG_TRACE(...)      AsyncLog::Output(LOG_LEVEL_TRACE,__FILE__,__LINE__,__VA_ARGS__)
#define LOG_DEBUG(...)      AsyncLog::Output(LOG_LEVEL_DEBUG,__FILE__,__LINE__,__VA_ARGS__)
#define LOG_INFO(...)       AsyncLog::Output(LOG_LEVEL_INFO,__FILE__,__LINE__,__VA_ARGS__)
#define LOG_WARN(...)       AsyncLog::Output(LOG_LEVEL_WARN,__FILE__,__LINE__,__VA_ARGS__)
#define LOG_ERROR(...)      AsyncLog::Output(LOG_LEVEL_ERROR,__FILE__,__LINE__,__VA_ARGS__)
#define LOG_SYSERR(...)     AsyncLog::Output(LOG_LEVEL_SYSERR,__FILE__,__LINE__,__VA_ARGS__)
#define LOG_FATAL(...)      AsyncLog::Output(LOG_LEVEL_FATAL,__FILE__,__LINE__,__VA_ARGS__)
#define LOG_CRITICAL(...)   AsyncLog::Output(LOG_LEVEL_CRITICAL,__FILE__,__LINE__,__VA_ARGS__)


class CellBuff
{
public:
    enum BuffStatus
    {
        BUFF_FREE,
        BUFF_FULL
    };

    CellBuff(int len);
    ~CellBuff();

    int AvailSize() const;
    bool IsEmpty() const ;
    bool append(const char* msg,int len);
    void clear();
    void persist(FILE* fp);

    


private:


};

class AsyncLog
{   
public:
    static bool Init();
    static bool Uninit();
    
    //不带文件名与行号的输出
    static bool Output(LOG_LEVEL nlevel,const char*pszFmt,...);
    //带有文件名与行号的输出
    static bool Output(LOG_LEVEL nlevel,const char* pszFileName,int nLineNo,const char *pszFmt,...);
    //输出缓冲区
    static bool OutputBuff(unsigned char* buff,int size);

private:
    AsyncLog() = delete;
    ~AsyncLog() = delete;

    AsyncLog(const AsyncLog&) = delete;
    AsyncLog& operator=(const AsyncLog&) = delete;

private:
    static bool         m_bToFile;
    static LOG_LEVEL    m_curLogLevel;
};

#endif